package com.gbb.common.utils;

import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader.TileMode;
import android.media.ExifInterface;
import android.text.TextUtils;

import com.gbb.common.chche.FileManager;
import com.gbb.common.chche.FileManager.FileEnum;
import com.gbb.common.log.LogUtils;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * Bitmap(位图)操作工具类
 *
 * @author gaobingbing
 */
public class BitmapUtil {


    /**
     * 图片变圆角方法.
     *
     * @param bitmap Bitmap
     * @param pixels 圆角度
     * @return 变圆角后的Bitmap
     */
    public static Bitmap toRoundCorner(Bitmap bitmap,int pixels) {
        if(bitmap != null) {
            Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),bitmap.getHeight(),Config.ARGB_8888);
            Canvas canvas = new Canvas(output);
            int color = 0xff424242;
            Paint paint = new Paint();
            Rect rect = new Rect(0,0,bitmap.getWidth(),bitmap.getHeight());
            RectF rectF = new RectF(rect);

			/* 设置取消锯齿效果 */
            paint.setAntiAlias(true);
            canvas.drawARGB(0,0,0,0);

			/* 设置颜色及绘制矩形 */
            paint.setColor(color);
            canvas.drawRoundRect(rectF,pixels,pixels,paint);

            paint.setXfermode(new PorterDuffXfermode(Mode.DST));
            canvas.drawBitmap(bitmap,rect,rect,paint);
            return output;
        } else {
            return null;
        }
    }

    /**
     * 图片去色,返回灰度图片
     *
     * @param bmpOriginal 传入的图片
     * @return 去色后的Bitmap
     */
    public static Bitmap toGrayscale(Bitmap bmpOriginal) {
        int width, height;
        height = bmpOriginal.getHeight();
        width = bmpOriginal.getWidth();

        Bitmap bmpGrayscale = Bitmap.createBitmap(width,height,Bitmap.Config.RGB_565);
        Canvas c = new Canvas(bmpGrayscale);
        Paint paint = new Paint();
        ColorMatrix cm = new ColorMatrix();
        cm.setSaturation(0);
        ColorMatrixColorFilter f = new ColorMatrixColorFilter(cm);
        paint.setColorFilter(f);
        c.drawBitmap(bmpOriginal,0,0,paint);
        return bmpGrayscale;
    }

    /**
     * 图片缩放
     *
     * @param bitmap Bitmap
     * @param newWidth 新的图片宽度
     * @param newHeight 新的图片高度
     * @return 压缩后的Bitmap
     */
    public static Bitmap zoomImage(Bitmap bitmap,int newWidth,int newHeight) {
        if(bitmap == null) {
            return null;
        }

        float scaleWidth = 1;
        float scaleHeight = 1;

        // 获取这个图片的宽和高
        int width = bitmap.getWidth();
        int height = bitmap.getHeight();

        // 创建操作图片用的matrix对象
        Matrix matrix = new Matrix();

        // 计算缩放率，新尺寸除原始尺寸
        if(newWidth == 0 && newHeight > 0) {
            scaleHeight = ((float)newHeight)/height;
            scaleWidth = scaleHeight;
        } else if(newHeight == 0 && newWidth > 0) {
            scaleWidth = ((float)newWidth)/width;
            scaleHeight = scaleWidth;
        } else if(newWidth > 0 && newHeight > 0) {
            scaleWidth = ((float)newWidth)/width;
            scaleHeight = ((float)newHeight)/height;
        }

        // 缩放图片动作
        matrix.postScale(scaleWidth,scaleHeight);
        return Bitmap.createBitmap(bitmap,0,0,width,height,matrix,true);
    }

    /**
     * 计算图片的压缩比例
     *
     * @param options Options
     * @param targetWidth 目标宽度
     * @param targetHeight 目标高度
     * @return 图片的压缩比例
     */
    public static int calculateInSampleSize(BitmapFactory.Options options,int targetWidth,int targetHeight) {
        int height = options.outHeight;
        int width = options.outWidth;
        int inSampleSize = 1;

        if(targetWidth > 0 && targetHeight <= 0) {
            // 缩放比以宽为标准
            inSampleSize = Math.round(width*1.f/targetWidth);
        } else if(targetHeight > 0 && targetWidth <= 0) {
            // 缩放比以高为标准
            inSampleSize = Math.round(height*1.f/targetHeight);
        } else {
            // 计算宽高压缩比例
            if(height > targetHeight || width > targetWidth) {
                int heightRatio = Math.round(height*1.f/targetHeight);
                int widthRatio = Math.round(width*1.f/targetWidth);
                inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;

            }
        }
        if(inSampleSize <= 0) {
            inSampleSize = 1;
        }
        return inSampleSize;
    }

    /**
     * 图片的压缩
     * 按照不同的图片的大小去压缩图片，返回一个压缩好的图片的本地地址
     *
     * @param mCurrentPhotoPath 图片压缩前的地址
     * @return 压缩完的图片的地址
     */
    public static String compressPic(String mCurrentPhotoPath,int targetWidth,int targetHeight) {
        String result = null; // 图片压缩后的地址
        FileOutputStream out = null;
        Bitmap bitmap = null;
        /*
         * 如果options.inJustDecodeBounds = true,
		 * 那么将不返回实际的bitmap,不给其分配内存空间,而里面只包括一些解码边界信息即图片大小信息
		 * 通过设置inJustDecodeBounds为true，获取到outHeight(图片原始高度)和outWidth(图片的原始宽度)
		 * 然后计算一个inSampleSize(缩放值)，然后就可以取图片了，这里要注意的是，inSampleSize 可能小于0，必须做判断。
		 */
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;

        int degree = getImageAngle(mCurrentPhotoPath);
        BitmapFactory.decodeFile(mCurrentPhotoPath,options);
        options.inSampleSize = calculateInSampleSize(options,targetWidth,targetHeight);
        options.inJustDecodeBounds = false;
        try {
            // 根据图片大小进行压缩质量的选择
            File filePhoto = new File(mCurrentPhotoPath);
            int qulity = 100;
            if(filePhoto.length() > 10000*1024) {
                qulity = 5;
            } else if(filePhoto.length() > 5000*1024) {
                qulity = 10;
            } else if(filePhoto.length() > 4000*1024) {
                qulity = 20;
            } else if(filePhoto.length() > 3000*1024) {
                qulity = 30;
            } else if(filePhoto.length() > 2000*1024) {
                qulity = 40;
            } else if(filePhoto.length() > 1000*1024) {
                qulity = 50;
            } else if(filePhoto.length() > 500*1024) {
                qulity = 60;
            } else if(filePhoto.length() > 400*1024) {
                qulity = 70;
            } else if(filePhoto.length() > 300*1024) {
                qulity = 80;
            } else if(filePhoto.length() > 100*1024) {
                qulity = 90;
            }

            bitmap = BitmapFactory.decodeFile(mCurrentPhotoPath,options);
            bitmap = rotaingImage(degree,bitmap);

            // 压缩并进行对接
            File file = new File(FileManager.get().getTempFile(FileEnum.IMAGE,mCurrentPhotoPath,true,true,true));
            out = new FileOutputStream(file);
            bitmap.compress(Bitmap.CompressFormat.JPEG,qulity,out);
            result = file.getAbsolutePath();
        } catch(Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if(out != null) {
                    out.close();
                }
            } catch(IOException e) {
                e.printStackTrace();
            }
            if(bitmap != null && !bitmap.isRecycled()) {
                bitmap.recycle();
            }
        }
        return result;
    }

    /**
     * 等比例压缩图片并缩放到目标尺寸
     *
     * @param localPicPath 图片本地地址
     * @param targetWidth 目标图片宽，若targetWidth=0，则压缩的时候以高的压缩比为标准
     * @param targetHeight 目标图片高,若targetHeight=0，则压缩的时候以宽的压缩比为标准
     * @return 压缩后的Bitmap
     */
    public static Bitmap compressPicture(String localPicPath,int targetWidth,int targetHeight,boolean isZoom) {
        Bitmap bitmap = null;
        if(localPicPath != null) {
            File picFile = new File(localPicPath);
            if(picFile.exists()) {
                BitmapFactory.Options options = new BitmapFactory.Options();
                options.inJustDecodeBounds = true;
                BitmapFactory.decodeFile(localPicPath,options);
                String compressBeforInfo = "原始大小:" + picFile.length()/1024 + "kb,原始尺寸(宽*高):" + options.outWidth + "*" + options.outHeight;
                options.inSampleSize = calculateInSampleSize(options,targetWidth,targetHeight);
                options.inJustDecodeBounds = false;

                bitmap = BitmapFactory.decodeFile(localPicPath,options);
                if(bitmap != null) {
                    if(isZoom) {
                        bitmap = zoomImage(bitmap,targetWidth,targetHeight);
                    }
                    LogUtils.i("图片压缩",compressBeforInfo + ",压后大小:" + bitmap.getByteCount()/1024 + "kb,压后尺寸(宽*高):" + targetWidth + "*" + targetHeight + ",压缩比例：" + options.inSampleSize);
                }
            }
        }
        return bitmap;
    }

    /**
     * 将Bitmap写入到磁盘
     *
     * @param bitmap Bitmap位图
     * @return 写入到磁盘的文件路径
     */
    public static String saveImage(Bitmap bitmap,String savePath) {
        if(TextUtils.isEmpty(savePath) || bitmap == null) {
            return null;
        }
        String result = null;
        FileOutputStream out = null;
        try {
            File file = new File(savePath);
            out = new FileOutputStream(file);
            bitmap.compress(Bitmap.CompressFormat.JPEG,100,out);
            result = file.getAbsolutePath();
        } catch(FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            try {
                if(out != null) {
                    out.close();
                }
            } catch(IOException e) {
                e.printStackTrace();
            }
        }
        return result;
    }


    /**
     * 获得带倒影的图片方法
     * 整个倒影图 = 原图 + 倒影图
     *
     * @param originalBitmap 原图
     * @param gapHeight 间隙高度
     * @param gapPaint 间隙画笔
     * @return 整个倒影位图
     */
    public static Bitmap createReflectionBitmap(Bitmap originalBitmap,int gapHeight,Paint gapPaint) {
        int width = originalBitmap.getWidth();
        int height = originalBitmap.getHeight();

        Matrix matrix = new Matrix();
        matrix.preScale(1,-1);

        // 倒影位图
        Bitmap reflectionBitmap = Bitmap.createBitmap(originalBitmap,0,height/2,width,height/2,matrix,false);
        // 整个倒影位图
        Bitmap bitmapWithReflection = Bitmap.createBitmap(width,(height + height/2),Config.ARGB_8888);

        Canvas canvas = new Canvas(bitmapWithReflection);
        canvas.drawBitmap(originalBitmap,0,0,null);
        if(gapPaint != null) {// 原图和倒影之间的间隙
            canvas.drawRect(0,height,width,height + gapHeight,gapPaint);
        }
        canvas.drawBitmap(reflectionBitmap,0,height + gapHeight,null);

        // 模糊倒影操作
        Paint paint = new Paint();
        LinearGradient shader = new LinearGradient(0,originalBitmap.getHeight(),0,bitmapWithReflection.getHeight() + gapHeight,0x70ffffff,0x00ffffff,TileMode.CLAMP);
        paint.setShader(shader);
        paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));
        canvas.drawRect(0,height + gapHeight,width,bitmapWithReflection.getHeight(),paint);

        return bitmapWithReflection;
    }

    /**
     * 获取图片的旋转度
     *
     * @param path 图片路径
     * @return 图片旋转度
     */
    private static int getImageAngle(String path) {
        int degree = 0;
        try {
            ExifInterface exifInterface = new ExifInterface(path);
            int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION,ExifInterface.ORIENTATION_NORMAL);
            switch(orientation) {
                case ExifInterface.ORIENTATION_ROTATE_90:
                    degree = 90;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_180:
                    degree = 180;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_270:
                    degree = 270;
                    break;
                default:
                    break;
            }
        } catch(IOException e) {
            e.printStackTrace();
        }
        return degree;
    }

    /**
     * 旋转图片
     *
     * @param angle 旋转的角度
     * @param bitmap 目标图片
     */
    private static Bitmap rotaingImage(int angle,Bitmap bitmap) {
        // 旋转图片 动作
        Matrix matrix = new Matrix();
        matrix.postRotate(angle);
        // 创建新的位图
        return Bitmap.createBitmap(bitmap,0,0,bitmap.getWidth(),bitmap.getHeight(),matrix,true);
    }

}
